﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using XSTDZ.ERP.Core.Repositories;
using XSTDZ.ERP.Domain.Models;
using XSTDZ.ERP.Application.DataContracts;
using AutoMapper;
using XSTDZ.ERP.Core.Generator;

namespace XSTDZ.ERP.Application.Implements
{
    public class UsualFinanceServiceImpl : ApplicationServiceBase, IUsualFinanceService
    {
        IRepository<UsualFinance> _billRepository;
        IRepository<UsualFinanceDetail> _billDetailRepository;
        IRepository<RemittanceRecord> _remittanceRecordRepository;
        public UsualFinanceServiceImpl(IRepositoryContext repositoryContext, IRepository<UsualFinance> billRepository, IRepository<UsualFinanceDetail> billDetailRepository, IRepository<RemittanceRecord> remittanceRecordRepository)
            : base(repositoryContext)
        {
            this._billRepository = billRepository;
            this._billDetailRepository = billDetailRepository;
            this._remittanceRecordRepository = remittanceRecordRepository;
        }

        public void Add(UsualFinanceDto usualFinanceDto)
        {
            var bill = Mapper.Map<UsualFinanceDto, UsualFinance>(usualFinanceDto);
            bill.Id = (Guid)new SequentialIdentityGenerator().Next;
            this._billRepository.Add(bill);
            this.Context.Commit();
        }

        public void Update(UsualFinanceDto usualFinanceDto)
        {
          //  var bill = Mapper.Map<UsualFinanceDto, UsualFinance>(usualFinanceDto);
            //var bill = _billRepository.GetByKey(usualFinanceDto.Id);
            //usualFinanceDto.OperationID = bill.OperationID;
            //usualFinanceDto.Operation_Time = bill.Operation_Time;
            //bill = Mapper.Map(usualFinanceDto, bill);
            //this._billRepository.Update(bill);
            //this.Context.Commit();
        }

        public void Delete(Guid ID,Guid detailID)
        {
            //var bill=this._billRepository.GetByKey(ID);
            //bill.Deleted = 1;
            //this._billRepository.Update(bill);
            //this.Context.Commit();

            this._billDetailRepository.Remove(t => t.Id == detailID);
            this.Context.Commit();
        }

        public UsualFinanceDto GetUsualFinance(Guid ID)
        {
            var workGroup = this._billRepository.GetByKey(ID);
            return Mapper.Map<UsualFinance, UsualFinanceDto>(workGroup);
        }

        public IList<UsualFinanceDto> GetUsualFinances()
        {
            var items = this._billRepository.GetAll();
            return Mapper.Map<IList<UsualFinance>, IList<UsualFinanceDto>>(items.ToList());
        }

        #region 日常开支明细

        public Guid AddUsualFinanceDetail(UsualFinanceDto usualFinanceDto, IEnumerable<UsualFinanceDetailDto> usualFinanceDetailDto)
        {

            var productDeliveryBill = Mapper.Map<UsualFinanceDto, UsualFinance>(usualFinanceDto);
            var productDeliveryBillDetails = Mapper.Map<IEnumerable<UsualFinanceDetailDto>, IEnumerable<UsualFinanceDetail>>(usualFinanceDetailDto);
            productDeliveryBill.Id = (Guid)new SequentialIdentityGenerator().Next;

            if (productDeliveryBillDetails != null && productDeliveryBillDetails.Count() != 0)
            {
                foreach (var item in productDeliveryBillDetails)
                {
                    if (!productDeliveryBill.UsualFinanceDetails.Contains(item))
                    {
                        item.Id = Guid.NewGuid();
                        item.UsualFinanceID = productDeliveryBill.Id;
                        productDeliveryBill.UsualFinanceDetails.Add(item);
                    }
                }
            }
            productDeliveryBill.CreateTime = DateTime.Now;
            productDeliveryBill.UpdateDate = DateTime.Now;
            productDeliveryBill.UpdateID = productDeliveryBill.CreateID;

            this._billRepository.Add(productDeliveryBill);
            this.Context.Commit();
            return productDeliveryBill.Id;
        }

        public Guid UpdateUsualFinanceDetail(UsualFinanceDto usualFinanceDto, IEnumerable<UsualFinanceDetailDto> usualFinanceDetailDtos)
        {
            var profitAndLossBill = this._billRepository.GetByKey(usualFinanceDto.Id);
            usualFinanceDto.CreateTime = profitAndLossBill.CreateTime;
            usualFinanceDto.CreateID = profitAndLossBill.CreateID;

            var targetBill = Mapper.Map(usualFinanceDto, profitAndLossBill);

            //处理明细
            var productCheckBillDetails = Mapper.Map<IEnumerable<UsualFinanceDetailDto>, IEnumerable<UsualFinanceDetail>>(usualFinanceDetailDtos);

            var updateItems = new List<UsualFinanceDetail>();
            var insertItems = new List<UsualFinanceDetail>();
            var itemIds = profitAndLossBill.UsualFinanceDetails.Select(d => d.Id).Cast<Guid>();

            productCheckBillDetails.Each(
                pd =>
                {
                    if (itemIds.Contains(pd.Id))
                    {
                        updateItems.Add(pd);
                    }
                    else
                    {
                        pd.Id = Guid.NewGuid();
                        pd.UsualFinanceID = usualFinanceDto.Id;
                        insertItems.Add(pd);
                    }
                }
                );
            if (updateItems.Count() != 0)
            {
                foreach (var p in targetBill.UsualFinanceDetails)
                {
                    foreach (var m in updateItems)
                    {
                        if (m.Id == p.Id)
                        {
                            p.RefeID = m.RefeID;
                            p.ProjectType = m.ProjectType;
                            p.GenerateFee = m.GenerateFee;
                            p.Remark = m.Remark;

                            p.HandlingTime = m.HandlingTime;
                            p.OperatorID = m.OperatorID;
                            break;
                        }
                    }
                }
            }
            if (insertItems.Count() != 0)
            {
                this._billDetailRepository.Add(insertItems);
            }
            try
            {
                this._billRepository.Update(targetBill);
                this.Context.Commit();
            }
            catch (Exception ex)
            {

                throw;
            }
            return targetBill.Id;
        }

        public UsualFinanceDetailDto GetUsualFinanceDetail(Guid usualFinanceId)
        {
            var bill = _billDetailRepository.GetByKey(usualFinanceId);
            return Mapper.Map<UsualFinanceDetail, UsualFinanceDetailDto>(bill);
        }

        public IEnumerable<UsualFinanceDetailDto> GetUsualFinanceDetails(Guid usualFinanceId)
        {
            var bills = this._billDetailRepository.GetAll(t => t.UsualFinanceID == usualFinanceId);
            var billDetail= Mapper.Map<IEnumerable<UsualFinanceDetail>, IEnumerable<UsualFinanceDetailDto>>(bills);
            if (billDetail != null && billDetail.Count() != 0)
            {
                var state = bills.FirstOrDefault().UsualFinance.BillState;

                billDetail.Each(t => t.BillState = state);
            }
            return billDetail;
        }

        #endregion
        #region 汇款记录

        public void AddRemittanceRecord(RemittanceRecordDto remittanceRecordDto)
        {
            var bill = Mapper.Map<RemittanceRecordDto, RemittanceRecord>(remittanceRecordDto);
            bill.Id = Guid.NewGuid();
            bill.CreateTime = DateTime.Now;

            bill.UpdateDate = DateTime.Parse("1900-01-01");
            bill.AffimDate = DateTime.Parse("1900-01-01");

            this._remittanceRecordRepository.Add(bill);
            this.Context.Commit();
        }

        public void UpdateRemittanceRecord(RemittanceRecordDto remittanceRecordDto)
        {
            var bill = Mapper.Map<RemittanceRecordDto, RemittanceRecord>(remittanceRecordDto);
            bill.UpdateDate = DateTime.Now;
            bill.AffimDate = DateTime.Parse("1900-01-01");
            this._remittanceRecordRepository.Update(bill);
            this.Context.Commit();
        }

        public RemittanceRecordDto GetRemittanceRecord(Guid ID)
        {
            var bill = _remittanceRecordRepository.GetByKey(ID);
            return Mapper.Map<RemittanceRecord, RemittanceRecordDto>(bill);
        }
        public void DeleteRemittanceRecord(Guid ID)
        {
            var bill = _remittanceRecordRepository.GetByKey(ID);
            bill.Deleted = 1;
            this._remittanceRecordRepository.Update(bill);
            this.Context.Commit();
        }
        #endregion





        public Guid ConfirmRemittanceRecord(Guid ID, Guid UserId, bool IsOk)
        {
            var bill = this._remittanceRecordRepository.GetByKey(ID);
            if (bill != null)
            {
                bill.AffimorID = UserId;
                bill.AffimState = IsOk ? 1 : 0;
                bill.AffimDate = DateTime.Now;
                if (bill.AffimState != 1)//打回
                {
                    bill.BillState = 0;
                }
                this._remittanceRecordRepository.Update(bill);
                this.Context.Commit();
            }
            return bill.Id;
        }


        public void ConvertUsualFinanceDeleteState(Guid usualFinanceId, IEnumerable<Guid> usualFinanceDetailIds)
        {
            var productOutBill = this._billRepository.GetByKey(usualFinanceId);
            var productBillItemIds = productOutBill.UsualFinanceDetails.Where(p => usualFinanceDetailIds.ToArray().Contains(p.Id));
            if (!productBillItemIds.Equals(null) && productBillItemIds.Count() != 0)
            {
                productBillItemIds.Each(t => { productOutBill.UsualFinanceDetails.Remove(t); });
            }
            this._billRepository.Update(productOutBill);
            this.Context.Commit();
        }

       
    }
}
